package org.xxpay.pay.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.xxpay.apibase.service.IDCAlizftpayChannelService;
import org.xxpay.apibase.service.IDCPaymentService;
import org.xxpay.apibase.vo.ApiPayOrder;
import org.xxpay.core.common.constant.Constant;
import org.xxpay.core.common.constant.RetEnum;
import org.xxpay.core.common.domain.api.msg.QueryRetMsg;
import org.xxpay.core.common.exception.ServiceException;
import org.xxpay.core.common.util.MyLog;
import org.xxpay.core.entity.PayOrder;
import org.xxpay.core.entity.PayPassageAccount;
import org.xxpay.core.entity.RefundOrder;
import org.xxpay.core.service.IXxPayPayService;
import org.xxpay.pay.channel.PayNotifyInterface;
import org.xxpay.pay.channel.PaymentInterface;
import org.xxpay.pay.channel.saaspay.SaaspayConfig;
import org.xxpay.pay.channel.saaspay.SaaspayController;
import org.xxpay.pay.channel.saaspay.SaaspayRefundService;
import org.xxpay.pay.mq.BaseNotify4AlizftpayTradeSettleConfirm;
import org.xxpay.pay.service.CommonService;
import org.xxpay.pay.service.LocalDynamicChannelService;

/**
 * @author: dingzhiwei
 * @date: 2018/5/29
 * @description:
 */
@Service(interfaceName = "org.xxpay.core.service.IXxPayPayService", version = Constant.XXPAY_SERVICE_VERSION, retries = Constant.DUBBO_RETRIES)
public class XxPayPayServiceImpl implements IXxPayPayService {

    private static final MyLog _log = MyLog.getLog(XxPayPayServiceImpl.class);

    @Autowired
    private CommonService commonService;

    @Autowired private LocalDynamicChannelService localDynamicChannelService;

    @Autowired private IDCAlizftpayChannelService dcAlizftpayChannelService;

    @Autowired private BaseNotify4AlizftpayTradeSettleConfirm baseNotify4AlizftpayTradeSettleConfirm;

    @Autowired private SaaspayRefundService SaaspayRefundService;


    @Override
    public QueryRetMsg queryChannelStatus(String payOrderId) {

        PayOrder payOrder = commonService.payOrderService.findByPayOrderId(payOrderId);
        String channelType = payOrder.getChannelType();

        QueryRetMsg retObj;
        try{

            Object instance = localDynamicChannelService.getPaymentInterface(channelType);  //获取通道对象示例

            if(instance == null){
                _log.warn("不支持的支付渠道, 实例化失败！.payOrderId={},channelType={}", payOrderId, channelType);
                throw new ServiceException(RetEnum.RET_COMM_OPERATION_FAIL);
            }

            if(instance instanceof PaymentInterface) {
                PaymentInterface paymentInterface = (PaymentInterface) instance;
                retObj = paymentInterface.query(payOrder);
            }else{

                IDCPaymentService paymentInterface = (IDCPaymentService)instance;

                //查询必要参数
                ApiPayOrder apiPayOrder = new ApiPayOrder();
                BeanUtils.copyProperties(payOrder, apiPayOrder);  //bean copy

                retObj = convertRes( paymentInterface.query(apiPayOrder, getPayParamJSON(payOrder.getPassageAccountId())) );
            }
            return retObj;
        }catch (Exception e) {
            _log.error("主动查询上游订单异常 payOrderId={}", payOrderId, e);
            throw new ServiceException(RetEnum.RET_COMM_OPERATION_FAIL);
        }
    }


    /** 该函数作用：  对外提供dubbo服务  **/
    @Override
    public void alizftTradeSettleConfirm(String alipayTradeNo, String payOrderId) {
        dcAlizftpayChannelService.tradeSettleConfirm(alipayTradeNo, payOrderId);
    }

    @Override
    public void alizftTradeSettleConfirmRetry(Long recordId) {
        baseNotify4AlizftpayTradeSettleConfirm.doNotify(recordId);
    }

    private JSONObject getPayParamJSON(Integer passageAccountId) {
        String payParam = "";
        PayPassageAccount payPassageAccount = commonService.payPassageAccountService.findById(passageAccountId);

        if(payPassageAccount == null) throw new ServiceException(RetEnum.RET_MGR_PAY_PASSAGE_ACCOUNT_NOT_EXIST);

        payParam = payPassageAccount.getParam();
        if(StringUtils.isBlank(payParam)) throw new ServiceException(RetEnum.RET_MGR_PAY_PASSAGE_ACCOUNT_NOT_EXIST); //仍然为空，说明配置有误

        return JSONObject.parseObject(payParam);
    }

    @Override
    public JSONObject refundOrder(RefundOrder refundOrder) {
        return SaaspayRefundService.refund(refundOrder);
    }

    /** 转换对象 **/
    private QueryRetMsg convertRes(org.xxpay.apibase.vo.api.msg.QueryRetMsg retMsg){
        return JSONObject.parseObject(JSON.toJSONString(retMsg), QueryRetMsg.class);
    }



}
